<?php
/**
 * ping++处理类
 * @author    zal
 *
 */
namespace Api\Controller;
use Api\Controller\BaseController;
use Think\Cache\Driver\File;
use Think\Log;

class PingppController extends BaseController {

    const STATUS = 8;//支付完成后的状态
    public static $api_key;
    public static $app_id;

    public function __construct()
    {
        Vendor("Pingpp.init");
        $configs=C('PINGPP_CONFIG');
        $pp_mode=C('PING_MODE');//开发模式
        if(empty($pp_mode)){
            $pp_mode=0;
        }
        if(!empty($configs)){
            if($pp_mode==0){
                self::$app_id=$configs["APIID"];
                self::$api_key=$configs["API_TEST_KEY"];
            }else{
                self::$app_id=$configs["APIID"];
                self::$api_key=$configs["API_LIVE_KEY"];
            }
        }
    }

    public function index(){
        $pub_key_path = ROOT_PATH.'Uploads/data/pingpp_rsa_public_key.pem';
        $pub_key_contents = file_get_contents($pub_key_path);
        $key="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLCgmN3L5EB2bt0QHgQ69ZyTB+
A00Y+X+YlHwP8VWrf0EPusbimkN99PRM4WvZxEey344lv7EcEhaxAuDesd+ywL80
DrR8Jlj4b5nIPeupyF6MS0OnnYvkRCaI2NCBE8X3SP4JDQi9M3zZu/QllFeKxaLt
QkMVXoaj/KzkD1EBFwIDAQAB";
        echo base64_encode($pub_key_contents);
    }

    public function pay_test(){
        $input_data = json_decode(file_get_contents('php://input'), true);
        $subject="";
        if(empty($input_data)){
            $input_data=$_POST;
        }
        if (empty($input_data['channel']) || empty($input_data['amount'])) {
            echo 'channel or amount is empty';
            exit();
        }
        $channel = strtolower($input_data['channel']);
        $amount = $input_data['amount'];
        $orderNo = substr(md5(time()), 0, 12);

// 设置请求签名密钥，密钥对需要你自己用 openssl 工具生成，把公钥填写到 https://dashboard.pingxx.com
        \Pingpp\Pingpp::setPrivateKeyPath(ROOT_PATH.'Uploads/data/rsa_private_key.pem');

        /**
         * $extra 在使用某些渠道的时候，需要填入相应的参数，其它渠道则是 array()。
         * 以下 channel 仅为部分示例，未列出的 channel 请查看文档 https://pingxx.com/document/api#api-c-new
         */
        $extra = array();
        switch ($channel) {
            case 'alipay_wap':
                $extra = array(
                    'success_url' => 'http://example.com/success',
                    'cancel_url' => 'http://example.com/cancel'
                );
                break;
            case 'bfb_wap':
                $extra = array(
                    'result_url' => 'http://example.com/result',
                    'bfb_login' => true
                );
                break;
            case 'upacp_wap':
                $extra = array(
                    'result_url' => 'http://example.com/result'
                );
                break;
            case 'wx_pub':
                $extra = array(
                    'open_id' => 'openidxxxxxxxxxxxx'
                );
                break;
            case 'wx_pub_qr':
                $extra = array(
                    'product_id' => 'Productid'
                );
                break;
            case 'yeepay_wap':
                $extra = array(
                    'product_category' => '1',
                    'identity_id'=> 'your identity_id',
                    'identity_type' => 1,
                    'terminal_type' => 1,
                    'terminal_id'=>'your terminal_id',
                    'user_ua'=>'your user_ua',
                    'result_url'=>'http://example.com/result'
                );
                break;
            case 'jdpay_wap':
                $extra = array(
                    'success_url' => 'http://example.com/success',
                    'fail_url'=> 'http://example.com/fail',
                    'token' => 'dsafadsfasdfadsjuyhfnhujkijunhaf'
                );
                break;
        }

        // 设置 API Key
        \Pingpp\Pingpp::setApiKey(self::$api_key);
        try {
            $ch = \Pingpp\Charge::create(
                array(
                    'subject'   => 'Your Subject',
                    'body'      => 'Your Body',
                    'amount'    => $amount,
                    'order_no'  => $orderNo,
                    'currency'  => 'cny',
                    'extra'     => $extra,
                    'channel'   => $channel,
                    'client_ip' => $_SERVER['REMOTE_ADDR'],
                    'app'       => array('id' => self::$app_id)
                )
            );
            echo $ch;
        } catch (\Pingpp\Error\Base $e) {
            header('Status: ' . $e->getHttpStatus());
            // 捕获报错信息
            echo $e->getHttpBody();
        }

    }

    /**
     * 支付
     * post请求
     * @param channel 支付渠道 alipay；wx；
     * @param amount 支付金额
     * @param order_no 订单号
     * @param order_volume 优惠券
     */
    public function pay(){
        // 此处为 Content-Type 是 application/json 时获取 POST 参数的示例
        $input_data = json_decode(file_get_contents('php://input'), true);
        $order_type_name=$order_flag_name = "";
        $subject = "";
        $metadata=array();
        if(empty($input_data)){
            $input_data=$_POST;
        }

        Log::write(var_export($input_data, true), 'input_data');
        //净水器先处理订单
        if (isset($input_data['order_flag']) and $input_data['order_flag'] == 4) {
            if(empty($input_data['channel']) || empty($input_data['amount'])){
                $this->ajaxReturn('支付渠道、支付金额不能为空','JSON');
            }
            if (!isset($input_data['brand']) or !in_array($input_data['brand'], array(1,2,3))) {
                $this->ajaxReturn('净水器品牌参数为空', 'JSON');
            }
            $res = $this->genWaterPurifierOrder($input_data);
            if($res['result'] == false){
                Log::write(var_export($res, true), 'genorder');
                $this->ajaxReturn($res['msg'], 'JSON');
            }else{
                $orderId = $res['msg'];
                $orderModel = M('WaterPurifierOrder');
                $order = $orderModel->where(array('order_id'=>$orderId))->find();
                if (!$order) {
                    $this->ajaxReturn('生成订单失败', 'JSON');
                }
                $input_data['order_no'] = $order['order_num'];
            }
            unset($order);
        }
        !isset($orderId) and $orderId = 0;
        if (empty($input_data['channel']) || empty($input_data['amount'])|| empty($input_data['order_no'])|| empty($input_data['order_flag'])) {
            $this->ajaxReturn('支付渠道、支付金额、订单号,订单类型都不能为空','JSON');
        }

        $order_code = self::getGuid();
        $subject = $input_data['channel']."订单";
        $order_flag = $input_data['order_flag'];

        if(!empty($input_data['order_volume'])){
            $volume_id = $input_data['order_volume'];
        }else{
            $volume_id = null;
        }
//        file_put_contents('/tmp/payment.txt','Payment_volume_id ===='.var_export($volume_id,true) . "\r\n", FILE_APPEND);

        if (!empty($order_flag)) {
            if($order_flag==1){
                $order_flag_name = "维修订单 -- ";
            }else if($order_flag == 2){
                $order_flag_name = "装修订单 -- ";
            }elseif($order_flag == 4){
                $order_flag_name = '净水器订单 -- ';
            }else{
                $order_flag_name = "商城订单 -- ";
            }
        }

        if (!empty($input_data['order_type'])) {
            if($input_data['order_type'] ==1){
                $order_type_name="即时下单";
            }elseif($input_data['order_type'] ==2){
                $order_type_name="预约下单";
            }elseif($input_data['order_type'] ==3){
                $order_type_name="取消订单";
                if(!empty($input_data['order_cancel_reason'])){
                    $order_cancel_reason = $input_data['order_cancel_reason'];
                }
                if(!empty($input_data['order_cancel_content'])) {
                    $order_cancel_content = $input_data['order_cancel_content'];
                }
            }elseif($input_data['order_type'] ==4){
                //发票支付使用
                if(empty($input_data['user_id']) || empty($input_data['tax']) || empty($input_data['money']) || empty($input_data['name']) || empty($input_data['content']) || empty($input_data['id'])  || empty($input_data['contacts_name']) || empty($input_data['contacts_phone']) ||  empty($input_data['method'])){
                    $this->ajaxReturn('所有选项都不能为空','JSON');
                }else{
                    if($input_data['method']==1 && (empty($input_data['address']) || empty($input_data['region']))){
                        $this->ajaxReturn('地址不能为空','JSON');
                    }elseif($input_data['method']==2 && empty($input_data['email'])){
                        $this->ajaxReturn('邮箱不能为空','JSON');
                    }
                }

            }
        }

        $channel = strtolower($input_data['channel']);
        $amount = $input_data['amount'];
        $orderNo = $input_data['order_no'];

        if($order_flag_name !="" || $order_type_name !=""){
            $subject = $order_flag_name.$order_type_name;
        }

        // 设置请求签名密钥，密钥对需要你自己用 openssl 工具生成，把公钥填写到 https://dashboard.pingxx.com
        \Pingpp\Pingpp::setPrivateKeyPath(ROOT_PATH.'Uploads/data/rsa_private_key.pem');
        // 也可以设置私钥内容
        // \PingppSDK\PingppSDK::setPrivateKey(file_get_contents(__DIR__ . '/your_rsa_private_key.pem'));

        /**
         * $extra 在使用某些渠道的时候，需要填入相应的参数，其它渠道则是 array()。
         * 以下 channel 仅为部分示例，未列出的 channel 请查看文档 https://pingxx.com/document/api#api-c-new
         */
        $extra = array();
        switch ($channel) {
            case 'alipay_wap':
                $extra = array(
                    'success_url' => 'http://example.com/success',
                    'cancel_url' => 'http://example.com/cancel'
                );
                break;
            case 'bfb_wap':
                $extra = array(
                    'result_url' => 'http://example.com/result',
                    'bfb_login' => true
                );
                break;
            case 'upacp_wap':
                $extra = array(
                    'result_url' => 'http://example.com/result'
                );
                break;
            case 'wx_pub':
                $extra = array(
                    'open_id' => 'openidxxxxxxxxxxxx'
                );
                break;
            case 'wx_pub_qr':
                $extra = array(
                    'product_id' => 'Productid'
                );
                break;
            case 'yeepay_wap':
                $extra = array(
                    'product_category' => '1',
                    'identity_id'=> 'your identity_id',
                    'identity_type' => 1,
                    'terminal_type' => 1,
                    'terminal_id'=>'your terminal_id',
                    'user_ua'=>'your user_ua',
                    'result_url'=>'http://example.com/result'
                );
                break;
            case 'jdpay_wap':
                $extra = array(
                    'success_url' => 'http://example.com/success',
                    'fail_url'=> 'http://example.com/fail',
                    'token' => 'dsafadsfasdfadsjuyhfnhujkijunhaf'
                );
                break;
        }
        $payData = array();
        // 设置 API Key
        \Pingpp\Pingpp::setApiKey(self::$api_key);

        try {
            if($input_data['order_type']==1 || $input_data['order_type']==2) {
                $charge_arr = array(
                    'order_no' => $order_code,
                    'amount' => $amount,
                    'app' => array('id' => self::$app_id),
                    'channel' => $channel,
                    'currency' => 'cny',
                    'client_ip' => $_SERVER['REMOTE_ADDR'],
                    'subject' => $subject,
                    'body' => $subject,
                    'extra' => $extra,
                    'metadata' => array("order_id" => $orderNo,"order_flag" => $order_flag, "order_volume" => $volume_id, 'true_order_id'=> $orderId),
                );
                $ch = \Pingpp\Charge::create(
                    $charge_arr
                );
                //$data=json_decode($ch,true);
                $user_id = 0;
                $orders = $this->checkOrderFlag($order_flag, $orderNo);

                if (!empty($orders)) {
                    $user_id = $orders["user_id"];
                }
                $data = $ch;
                $pay_extra = serialize($extra);
                $payData = $charge_arr;
                unset($payData["extra"]);
                unset($payData["currency"]);
                unset($payData["app"]);
                unset($payData["metadata"]);
                $payData["extra"] = $pay_extra;
                $payData["order_type"] = $order_flag;
                $payData["addtime"] = time();
                $payData["total"] = $amount;
                $payData["user_id"] = $user_id;
                $payData['order_id'] = $orderNo;
                $payData['order_no'] = $order_code;

                file_put_contents("/tmp/test.txt","orderCode==========".$order_code."\r\n",FILE_APPEND);
                $isExists = M("UserPayRecord")->where(array("order_id" => $orderNo, "event" => 1))->find();

                if (empty($isExists)) {
                    $result = M("UserPayRecord")->add($payData);
                    file_put_contents("/tmp/test.txt","orderCode2==========".$order_code."\r\n",FILE_APPEND);
                    \Think\Log::record("pay-result:" . $result . " UserPayRecord===" . var_export($payData, true));
                } else {
                    $wheData['order_id'] = $orderNo;
                    unset($payData['order_id']);
                    $isExists = M("UserPayRecord")->where($wheData)->save($payData);
                    file_put_contents("/tmp/test.txt","orderCode3==========".$order_code."\r\n",FILE_APPEND);
                    file_put_contents("/tmp/test.txt","orderCode4==========".$isExists."\r\n",FILE_APPEND);
                    \Think\Log::record("pay-result-exists UserPayRecord===" . var_export($isExists, true));
                }

            }elseif($input_data['order_type']==3){
                $charge_arr = array(
                    'order_no' => $order_code,
                    'amount' => $amount,
                    'app' => array('id' => self::$app_id),
                    'channel' => $channel,
                    'currency' => 'cny',
                    'client_ip' => $_SERVER['REMOTE_ADDR'],
                    'subject' => $subject,
                    'body' => $subject,
                    'extra' => $extra,
                    'metadata' => array("order_id" => $orderNo,"order_flag" => $order_flag, "order_type"=>'3', "order_cancel_reason" => $order_cancel_reason,"order_cancel_content"=>$order_cancel_content),
                );

                $ch = \Pingpp\Charge::create(
                    $charge_arr
                );
//                $data=json_decode($ch,true);
                $user_id = 0;
                $orders = $this->checkOrderFlag($order_flag, $orderNo);
                if (!empty($orders)) {
                    $user_id = $orders["user_id"];
                }
                $data = $ch;
                $pay_extra = serialize($extra);

                $payCancelData['user_id'] = $user_id;
                $payCancelData['order_id'] = $orderNo;
                $payCancelData['order_no'] = $order_code;
                $payCancelData['subject'] = $charge_arr['subject'];
                $payCancelData['diagnose_price'] = $charge_arr['amount'];
                $payCancelData['amount'] = $charge_arr['amount'];
                $payCancelData['extra'] = $pay_extra;
                $payCancelData['channel'] = $channel;
                $payCancelData['client_ip'] = $_SERVER['REMOTE_ADDR'];
                $payCancelData['order_type'] = $order_flag;
                $payCancelData['addtime'] = time();

                $isExists = M('UserPayCancelRecord')->where("order_id = $orderNo")->find();

                if(empty($isExists)){
                    $return = M('UserPayCancelRecord')->add($payCancelData);
                    file_put_contents('/tmp/payment.txt','Order_Cancel_ADD_RECORD'.var_export($return,true) . "\r\n", FILE_APPEND);
                }else{
                    $wheCancelData['order_id'] = $orderNo;
                    unset($payCancelData['order_id']);
                    $isExists = M('UserPayCancelRecord')->where($wheCancelData)->save($payCancelData);
                    file_put_contents('/tmp/payment.txt','Order_Cancel_Pay ==== '.var_export($isExists,true) . "\r\n", FILE_APPEND);
                }
            }elseif($input_data['order_type']==4){
                $invoice_No='No'.build_order_no();
                $metadata['name']=$input_data['name'];    //发票抬头
                $metadata['number']=$invoice_No;    //发票编号
                $metadata['add_time']=time();    //申请时间
                $metadata['content']=$input_data['content'];    //发票内容
                $metadata['contacts_name']=$input_data['contacts_name'];   //联系人姓名
                $metadata['contacts_phone']=$input_data['contacts_phone'];   //联系人电话
                $metadata['money']=$input_data['money'];        //发票金额
                $metadata['tax']=$input_data['tax'];            //税费
                $metadata['postage']=$input_data['postage'];            //快递费
                $metadata['order_id']=$input_data['id'];        //订单id
                $metadata['user_id']=$input_data['user_id'];     //用户id
                $metadata['region']=$input_data['region'];      //地区
                $metadata['method']=$input_data['method'];      //方式
                $metadata['amount']=$input_data['amount']/100;      //支付金额
                $metadata['channel']=$input_data['channel'];      //支付渠道
                $metadata['address']=empty($input_data['address'])?'':$input_data['address'];   //邮寄地址
                $metadata['email']=empty($input_data['email'])?'':$input_data['email'];          //电子邮箱


                file_put_contents('/tmp/payment.txt',"这里是发票支付==================================================" ."\r\n", FILE_APPEND);

                $in_id=M('invoice')->add($metadata);
                $rewher['repair_order_num_alias']=array('in',$input_data['id']);
                $saea['is_mail']=0;
                M('repair_order')->where($rewher)->save($saea);
                $charge_arr = array(
                    'order_no' => $invoice_No,
                    'amount' => $amount,
                    'app' => array('id' => self::$app_id),
                    'channel' => $channel,
                    'currency' => 'cny',
                    'client_ip' => $_SERVER['REMOTE_ADDR'],
                    'subject' => $subject,
                    'body' => $subject,
                    'extra' => $extra,
                    'metadata' => array('id'=>$in_id,'order_id'=>$input_data['id'],'order_type'=>4));

                $ch = \Pingpp\Charge::create(
                    $charge_arr
                );
                $user_id = 0;
                $orders = $this->checkOrderFlag($order_flag, $orderNo);
                if (!empty($orders)) {
                    $user_id = $orders["user_id"];
                }
                $data = $ch;


            }
            $this->ajaxReturn($data,'JSON');

        } catch (\Pingpp\Error\Base $e) {
            header('Status: ' . $e->getHttpStatus());
            $data["code"]=1017;
            $data["msg"]=$e->getHttpStatus();
            $data['error'] = $e->getHttpBody();
            // 捕获报错信息
            $this->ajaxReturn($data,'JSON');
        }
    }


    /**
     * 退款
     * @param charge_id 支付的Charge对象id
     * @param amount 退款金额
     * @param description 退款详情
     */
    public function refund($charge_id,$amount,$description){
        \Pingpp\Pingpp::setPrivateKeyPath(ROOT_PATH.'Uploads/data/rsa_private_key.pem');
        $input_data = json_decode(file_get_contents('php://input'), true);
//        if(empty($input_data)){
//            $input_data=$_POST;
//        }
//        if (empty($input_data['charge_id']) || empty($input_data['amount'])) {
//            $this->ajaxReturn('charge_id or amount is empty','JSON');
//        }

        \Pingpp\Pingpp::setApiKey(self::$api_key);
        $ch = \Pingpp\Charge::retrieve($charge_id);
        $re = $ch->refunds->create(
            array(
                'amount' => $amount,
                'description' => $description
            )
        );
        $data=json_decode($re,true);
        return $data;
//        $this->ajaxReturn($data,'JSON');
    }


    /**
     * 转账
     */
    public function transfer(){
        \Pingpp\Pingpp::setApiKey(self::$api_key);
        try {
            $tr = \Pingpp\Transfer::create(
                array(
                    'amount'    => 100,
                    'order_no'  => date('YmdHis') . (microtime(true) % 1) * 1000 . mt_rand(0, 9999),
                    'currency'  => 'cny',
                    'channel'   => 'wx_pub',
                    'app'       => array('id' => self::$api_id),
                    'type'      => 'b2c',
                    'recipient' => 'o9zpMs9jIaLynQY9N6yxcZ',
                    'description' => 'testing',
                    'extra' => array('user_name' => 'User Name', 'force_check' => false)
                )
            );
            $data=json_decode($tr,true);
            $this->ajaxReturn($data,'JSON');
        } catch (\Pingpp\Error\Base $e) {
            header('Status: ' . $e->getHttpStatus());
            $data=($e->getHttpBody());
            $this->ajaxReturn($data,'JSON');
        }
    }

    /**
     * 通知
     */
    public function webhooks(){
        $data=$metadata=array();
        $code=0;
        $raw_data = file_get_contents('php://input');
        if(empty($raw_data)){
            $raw_data=$_POST;
        }
        \Think\Log::record("Pingpp webhooks raw_data===".$raw_data);
        file_put_contents('/tmp/payment.txt',"Pingpp webhooks Raw_data=======".var_export($raw_data,true) ."\r\n", FILE_APPEND);

        // 示例
        // $raw_data = '{"id":"evt_eYa58Wd44Glerl8AgfYfd1sL","created":1434368075,"livemode":true,"type":"charge.succeeded",
        //"data":{"object":{"id":"ch_bq9IHKnn6GnLzsS0swOujr4x","object":"charge","created":1434368069,"livemode":true,"paid":true,"refunded":false,
        //                  "app":"app_vcPcqDeS88ixrPlu","channel":"wx","order_no":"2015d019f7cf6c0d","client_ip":"140.227.22.72","amount":100,
        //                  "amount_settle":0,"currency":"cny","subject":"An Apple","body":"A Big Red Apple","extra":{},"time_paid":1434368074,
        //                  "time_expire":1434455469,"time_settle":null,"transaction_no":"1014400031201506150354653857",
        //      "refunds":{"object":"list","url":"/v1/charges/ch_bq9IHKnn6GnLzsS0swOujr4x/refunds","has_more":false,"data":[]},"amount_refunded":0,
        //                  "failure_code":null,"failure_msg":null,"metadata":{},"credential":{},"description":null}},
        //                  "object":"event","pending_webhooks":0,"request":"iar_Xc2SGjrbdmT0eeKWeCsvLhbL"}';

        $headers = \Pingpp\Util\Util::getRequestHeaders();
            // 签名在头部信息的 x-pingplusplus-signature 字段
        $signature = isset($headers['X-Pingplusplus-Signature']) ? $headers['X-Pingplusplus-Signature'] : NULL;
        // 示例
        // $signature = 'BX5sToHUzPSJvAfXqhtJicsuPjt3yvq804PguzLnMruCSvZ4C7xYS4trdg1blJPh26eeK/P2QfCCHpWKedsRS3bPKkjAvugnMKs+3Zs1k+PshAiZsET4sWPGNnf1E89Kh7/2XMa1mgbXtHt7zPNC4kamTqUL/QmEVI8LJNq7C9P3LR03kK2szJDhPzkWPgRyY2YpD2eq1aCJm0bkX9mBWTZdSYFhKt3vuM1Qjp5PWXk0tN5h9dNFqpisihK7XboB81poER2SmnZ8PIslzWu2iULM7VWxmEDA70JKBJFweqLCFBHRszA8Nt3AXF0z5qe61oH1oSUmtPwNhdQQ2G5X3g==';

        // 请从 https://dashboard.pingxx.com 获取「Ping++ 公钥」
        //\Think\Log::record("signature:".$signature);
        $pub_key_path = ROOT_PATH.'Uploads/data/pingpp_rsa_public_key.pem';
        //\Think\Log::record("pub_key_path:".$pub_key_path);
        $result = $this->verify_signature($raw_data, $signature, $pub_key_path);
        \Think\Log::record("Pingpp webhooks verify_signature result===".$result);
        if ($result === 1) {

             // 验证通过
        } elseif ($result === 0) {
            $code=http_response_code(400);
            $data["code"]=$code;
            $data["msg"]='verification failed';
            $this->ajaxReturn($data,'JSON');
        } else {
            $code=http_response_code(400);
            $data["code"]=$code;
            $data["msg"]='verification error';
            $this->ajaxReturn($data,'JSON');
        }

        $event = json_decode($raw_data, true);

        file_put_contents('/tmp/payment.txt',"Pingpp[webhooks] event===".var_export($event,true) . "\r\n", FILE_APPEND);
        $charge = $event['data']['object']['metadata'];
        $ordeType = isset($charge['order_type']) ? $charge['order_type'] : 0;

        if($event['type'] == 'charge.succeeded' && $ordeType == '3'){
            $CancelResult = $this->cancel($event);
            if($CancelResult['code']==200){
                $UpdateResult = $this->UpdateCancelRecord($event,1);
                file_put_contents('/tmp/payment.txt','UpdatePayCancelRecord======'.var_export($UpdateResult)."\r\n", FILE_APPEND);
            }
            file_put_contents('/tmp/payment.txt','Pingpp webhooks charge.succeeded: result==='.var_export($result,true) . "\r\n", FILE_APPEND);

            if($result["code"]!=200){
                $this->ajaxReturn($result,'JSON');
            }
            $code=http_response_code(200); // PHP 5.4 or greater

        }else if ($event['type'] == 'charge.succeeded') {
            if($ordeType==4){
                //发票支付
                $CancelResult = $this->invoiceSuccess($event['data']['object']['metadata']);
                $repair_order_num_alias=$event['data']['object']['metadata']['order_id'];
                $rewher['repair_order_num_alias']=array('in',$repair_order_num_alias);
                $saea['is_mail']=1;
                M('repair_order')->where($rewher)->save($saea);
                file_put_contents('/tmp/payment.txt',"这里发票支付成功是回调======================================".var_export($repair_order_num_alias,true)."\r\n",FILE_APPEND);
                if(!$CancelResult){
                    file_put_contents('/tmp/payment.txt','UpdatePayInvoice======'.date('Y-m-d H:i:s',time()).var_export($CancelResult)."\r\n", FILE_APPEND);
                }
                file_put_contents('/tmp/payment.txt','Pingpp webhooks charge.succeeded: result==='.var_export($result,true) . "\r\n", FILE_APPEND);

                if($result["code"]!=200){
                    $this->ajaxReturn($result,'JSON');
                }
                $code=http_response_code(200); // PHP 5.4 or greater
            }else{
                $result=$this->updateOrder($event,1);
                file_put_contents('/tmp/payment.txt','Pingpp webhooks charge.succeeded: result==="'.var_export($event,true) . "\r\n", FILE_APPEND);
                Log::write(var_export($result, true), 'result');
                $charge = $event['data']['object'];
                if(!empty($charge["metadata"])){
                    $metadata = $charge["metadata"];
                    if(!empty($metadata["order_volume"])){
                        $volume=$this->updateOrderVolume($event);
                        file_put_contents('/tmp/test.txt','Payment_order_volume ===='.var_export($volume,true) . "\r\n", FILE_APPEND);
                    }
                }
                if($result["code"]!=200){
                    $this->ajaxReturn($result,'JSON');
                }
                $code=http_response_code(200); // PHP 5.4 or greater
            }


        } elseif ($event['type'] == 'refund.succeeded') {
//            $refund = $event['data']['object'];
            $order_id = $event['data']['object']['charge_order_no'];
            $description = $event['data']['object']['description'];
            file_put_contents('/tmp/charge.txt','RepairOrderRefund================='.var_export($event,true) . "\r\n", FILE_APPEND);
            //更新支付状态
            $maps['order_no'] = $order_id;
            $Update['event'] = 2;
            $refundOrder = M('user_pay_record')->where($maps)->save($Update);
            file_put_contents('/tmp/charge.txt','RepairOrderRefund=====UpdatePay============'.var_export($refundOrder,true) . "\r\n", FILE_APPEND);
            //更新申请状态
            $wheOrder['repair_order_num_alias'] = $order_id;
            $RepairOrder = M('repair_order')->field('repair_order_id')->where($wheOrder)->find();
            file_put_contents('/tmp/charge.txt','RepairOrderRefund======UpdateApply==========='.var_export($RepairOrder,true) . "\r\n", FILE_APPEND);

            if($RepairOrder){
                $where['order_id'] = $RepairOrder['repair_order_id'];
                $set['feedback'] = $description;
                $set['status'] = 1;
                M('repair_order_refund')->where($where)->save($set);
                $updateOrder['status'] = 15;
                M('repair_order')->where($wheOrder)->save($updateOrder);

                $status['order_type'] = 1;
                $status['order_id'] =$RepairOrder['repair_order_id'];
                $status['add_time'] = time();
                $status['status'] = '15';
                M('order_status_history')->add($status);

            }else{
                $array = array('err_code'=>404,'err_msg'=>'订单不存在');
                file_put_contents('/tmp/charge.txt','RepairOrderNotExist================='.var_export($array,true) . "\r\n", FILE_APPEND);
            }
            // ...
            $code= http_response_code(200); // PHP 5.4 or greater

        } elseif($event['type'] == 'charge.succeeded' && $ordeType == '4'){
            //发票支付
            $CancelResult = $this->invoiceSuccess($event['data']['object']['metadata']);
            $repair_order_num_alias=$event['data']['object']['metadata']['order_id'];
            $rewher['repair_order_num_alias']=array('in',$repair_order_num_alias);
            $saea['is_mail']=1;
            M('repair_order')->where($rewher)->save($saea);
            file_put_contents('/tmp/payment.txt',"这里发票支付成功是回调======================================".var_export($repair_order_num_alias,true)."\r\n",FILE_APPEND);
            if(!$CancelResult){
                file_put_contents('/tmp/payment.txt','UpdatePayInvoice======'.date('Y-m-d H:i:s',time()).var_export($CancelResult)."\r\n", FILE_APPEND);
            }
            file_put_contents('/tmp/payment.txt','Pingpp webhooks charge.succeeded: result==='.var_export($result,true) . "\r\n", FILE_APPEND);

            if($result["code"]!=200){
                $this->ajaxReturn($result,'JSON');
            }
            $code=http_response_code(200); // PHP 5.4 or greater

        }else {
            /**
             * 其它类型 ...
             * - summary.daily.available
             * - summary.weekly.available
             * - summary.monthly.available
             * - transfer.succeeded
             * - red_envelope.sent
             * - red_envelope.received
             * ...
             */
            //$code=http_response_code(200);
            $code=http_response_code(400);
            // 异常时返回非 2xx 的返回码
            // http_response_code(400);
        }
        //$data["code"]=$code;
       // $data["msg"]='ok';
        //$this->ajaxReturn($data,'JSON');
        echo $code;
    }

    // 验证 webhooks 签名方法
    private function verify_signature($raw_data, $signature, $pub_key_path) {
        $pub_key_contents = file_get_contents($pub_key_path);
        // php 5.4.8 以上，第四个参数可用常量 OPENSSL_ALGO_SHA256
        //\Think\Log::record("base64_decode_signature:".base64_decode($signature));
        //\Think\Log::record("pub_key_contents:".$pub_key_contents);
        return openssl_verify($raw_data, base64_decode($signature), $pub_key_contents, 'sha256');
    }

    /**
     * 支付成功后，如果有优惠券，更改价格插入优惠券
     * @param $event 通知返回的数组
     * @param $order_volume 优惠券id
     */

    private function updateOrderVolume($event){
        $data=$metadata=array();
        file_put_contents('/tmp/payment.txt','UpdateOrderevent111 ===='.var_export($event,true) . "\r\n", FILE_APPEND);
        if(empty($event)){
            $data["code"]=403;
            $data["msg"]="非法操作";
            return $data;
        }
        $charge = $event['data']['object'];


        if(!empty($charge["metadata"])){
            $metadata=$charge["metadata"];
            if(isset($metadata["order_volume"])){
                $order_volume = $metadata["order_volume"];
                $orderNo = $metadata["order_id"];
            }
        }
        $time = time();
        $exist = M()->table('zsf_repair_order rep')->field('rep.repair_order_id,rep.user_id,rep.protocol_id,rep.total as order_total,rep.fixed_price,vol.total as volume_total')
            ->join("LEFT JOIN zsf_volume_list vol on vol.user_id = rep.user_id")
            ->where("rep.repair_order_num_alias = $orderNo and vol.status = 1 and vol.volume_list_id = $order_volume and $time < vol.end_time")
            ->select();

        if($exist){
            //更新订单详情信息
            $whereMap['repair_order_id'] = array('eq',$exist[0]['repair_order_id']);
            $saveMap['volume_list_id'] = $order_volume;
            $saveOrder = M('repair_order')->where($whereMap)->save($saveMap);

            if($saveOrder){
                //更新优惠券的状态
                $saveVolume['status'] = 2;
                $saveVolume['use_time'] = time();
                $saveVolume['use_scene'] = $orderNo;
                $VolumeStatus = M('volume_list')->where("volume_list_id = $order_volume")->save($saveVolume);
                file_put_contents('/tmp/payment.txt','Payment_volume_status ===='.var_export($VolumeStatus,true) . "\r\n", FILE_APPEND);

                $data["code"]=200;
                $data["msg"]="success";
            }else{
                $data["code"]=200;
                $data["msg"]="error";
            }
        }

        return $data;
    }

    /**
     * 支付成功后，更改订单相关信息
     * @param $event   通知返回的数组
     * @param $event_type 订单事件类型
     */

    private function updateOrder($event,$event_type=1){
        $data=$metadata=array();
        if(empty($event)){
            $data["code"]=403;
            $data["msg"]="非法操作";
            return $data;
        }
        $roshModel = M('OrderStatusHistory');
        $charge = $event['data']['object'];
        $channel = $charge["channel"];
        $order_flag = 0;

        if(!empty($charge["metadata"])){
            $metadata=$charge["metadata"];
            if(isset($metadata["order_flag"])){
                $order_flag=$metadata["order_flag"];
                $orderNo = $metadata["order_id"];
            }
        }
        $orders=$this->checkOrderFlag($order_flag,$orderNo);

        \Think\Log::record("Pingpp webhooks updateOrder: orders===".var_export($orders,true));

        if(!empty($orders)){
            if ($orders['order_type'] == 4) { //净水器订单
                $res = $this->updatePurifierOrder($orders, $event, $event_type);
                \Think\Log::record("Pingpp webhooks updateWaterPurifierOrder: res===".var_export($res,true));
                return $res;
            }
            $orders["orderNo"]=$orderNo;
            $orders["channel"]=$channel;
            $orders["amount"]=$charge["amount"];

            $order_id = $orders["order_id"];
            $order_type = $orders["order_type"];
            $worker_user_id = $orders["worker_user_id"];
            $amount = $charge["amount"]/100;
            //订单信息
            $repairOrder = M('repair_order')->where("repair_order_id = $order_id")->find();
            $repairOrderId = $repairOrder['repair_order_num_alias'];
            $repairOrderProtocol = M('repair_order_protocol')->where("protocol_id = $repairOrder[protocol_id]")->find();
            if($repairOrder['tip']!=0.00){
                //添加小费至余额
                $UserTipMoney = M('user_money')->where("user_id = $worker_user_id")->setInc("balance",$repairOrder['tip']);
                //添加流水
                $this->addToMoneyHistory($worker_user_id,4,$order_id,$repairOrder[protocol_id],$repairOrder['tip'],1,NULL,5,'订单'.$repairOrderId.'小费已到余额');
                file_put_contents('/tmp/test.txt',"addtoUserTipMoney=====".var_export($UserTipMoney,true) ."\r\n" , FILE_APPEND);
                $amount -= $repairOrder['tip'];
            }
            //更新支付金额到订单信息表
            $repairOrderSave['amount_paid'] = $amount;
            $SavePaid = M('repair_order')->where("repair_order_id = $order_id")->save($repairOrderSave);
            file_put_contents('/tmp/test.txt','SAVEPAID================'.var_export($SavePaid,true) . "\r\n", FILE_APPEND);

            //添加维修金金额至钱包
            $UserMaintainMoney = M('user_money')->where("user_id = $worker_user_id")->setInc("repair_money",$repairOrderProtocol['maintain']);
            file_put_contents('/tmp/test.txt',"addtoUserMoney=======maintain======".var_export($UserMaintainMoney,true) ."\r\n" , FILE_APPEND);
            //添加流水
            $this->addToMoneyHistory($worker_user_id,4,$order_id,$repairOrder[protocol_id],$repairOrderProtocol['maintain'],1,NULL,1,"订单".$repairOrderId."支付完成，维修金额已到钱包");

            //添加维保金至钱包
            $UserBondMoney = M('user_money')->where("user_id = $worker_user_id")->setInc("repair_bond",$repairOrderProtocol['bond']);
            file_put_contents('/tmp/test.txt',"addtoUserMoney========bond========".var_export($UserBondMoney,true) ."\r\n" , FILE_APPEND);
            //添加流水
            $this->addToMoneyHistory($worker_user_id,4,$order_id,$repairOrder[protocol_id],$repairOrderProtocol['bond'],1,NULL,2,"订单".$repairOrderId."支付完成，维保金额已到钱包");

            //查询该订单状态记录是否存在，存在则不进行任何操作
            $isExists=$roshModel->where(" status = ".self::STATUS." and count = 0 and order_type = ".$order_type." and order_id = ".$order_id)->find();
            file_put_contents('/tmp/test.txt',"historyIsExists==============".var_export($isExists,true) ."\r\n" , FILE_APPEND);
            if(empty($isExists)){
                $data=$this->updateOrderStatus($orders,$event,$event_type);
            }else{
                $data["code"]=200;
                $data["msg"]="ok";
            }
        }else{
            $data["code"]=2002;
            $data["msg"]="该订单号不存在订单";
        }
        return $data;
    }

    /**
     * 更新订单状态
     * @param $orders 订单相关的数据数组
     * @param $event 通知返回的数组
     * @param $event_type 订单事件类型
     * @return array
     */
    private function updateOrderStatus($orders,$event,$event_type=1){
        $data=array();
        $renovationModel=M('RenovationOrder');
        $repairModel=M('RepairOrder');
        $roshModel=M('OrderStatusHistory');

        $roshModel->startTrans();
        $order_flag=$orders["order_type"];
        $order_id=$orders["order_id"];
        $orderNo=$orders["orderNo"];
        $channel=$orders["channel"];
        $user_id=$orders["user_id"];

        $insetData["order_type"]=$order_flag;
        $insetData["order_id"]=$order_id;
        $insetData["status"]=self::STATUS;
        $insetData["add_time"]=time();

        $addToHistory = $roshModel->add($insetData);
        file_put_contents("/tmp/test.txt","anyyyyyyyyyyyyyy====".var_export($addToHistory,true)."\r\n",FILE_APPEND);

        if($addToHistory===false){
            $roshModel->rollback();
            $data["code"]=403;
            $data["msg"]="订单状态更新失败";
        }else{
            $payment_code=0;
            if($channel=="wx"){
                $payment_code=2;
            }else if($channel=="alipay"){
                $payment_code=1;
            }
            $orderData["pay_time"]=time();
            $orderData["status"]=self::STATUS;
            $orderData["payment_code"]=$payment_code;

            //根据不同类型订单，更新不同类型的订单数据
            if($order_flag==1){
                $result=$repairModel->where(array("repair_order_num_alias"=>$orderNo))->save($orderData);
            }else if($order_flag==2){
                $result=$renovationModel->where(array("renovation_order_num_alias"=>$orderNo))->save($orderData);
            }
            file_put_contents('/tmp/test.txt','FUCKKK --- result================'.var_export($result,true) . "\r\n", FILE_APPEND);

            if($result===false){
                $roshModel->rollback();
                $data["code"]=403;
                $data["msg"]="订单状态更新失败";
            }else{
                $result=$this->updateUserPayRecord($orderNo,$order_flag,$event,$event_type,$user_id);

                if($result===false){
                    $roshModel->rollback();
                    $data["code"]=403;
                    $data["msg"]="订单状态更新失败";
                }else{
                    $roshModel->commit();
//                    $this->pushPayInfo($orders["amount"],$orders["user_id"]);
                    $data["code"]=200;
                    $data["msg"]="ok";
                }
            }
        }
        return $data;
    }

    /**
     * 更新净水器订单状态
     * @param  array  $orders     订单信息
     * @param  array  $event      支付结果信息
     * @param  int $event_type 订单类型
     * @return [type]              [description]
     */
    private function updatePurifierOrder($orders,$event,$event_type=1){
        
        $orderFlag = $orders["order_type"];
        $orderId = $orders["order_id"];
        $userId = $orders["user_id"];

        $orderModel = M('WaterPurifierOrder');
        $map['user_id'] = $userId;
        $map['order_id'] = $orderId;
        $map['order_status'] = 1;
        $map['is_deleted'] = 0;
        $order = $orderModel->where($map)->find();

        if (!$order) {
            return array('code'=>403,'msg'=>'查找不到对应订单');
        }
        //订单已支付，无须更新 
        if ($order['pay_time'] > 0 and $order['payment_status'] == 1) {
            return array('code'=>200, 'msg'=>'ok');
        }
        $orderNo = $order['order_num'];

        $orderModel->startTrans();

        $data['pay_time'] = time();
        $data['payment_status'] = 1;
        if($order['payment_code'] == 3){
            $data['finish_time'] = time();
        }
        //更新订单
        $res = $orderModel->where(array('order_id'=>$orderId))->save($data);

        if ($res === false) {
            $orderModel->rollback();
            return array('code'=>403,'msg'=>'订单状态更新失败');
        }else{
            //更新支付流水
            $result=$this->updateUserPayRecord($orderNo,$orderFlag,$event,$event_type,$userId);
            if($result === false){
                $orderModel->rollback();
                return array('code'=>403,'msg'=>'订单状态更新失败');
            }else{
                $orderModel->commit();
                return array('code'=>200, 'msg'=>'ok');
            }
        }
        
    }
    /**
     * 检测是哪种类型的订单
     * @param $flag
     * @param $orderNo
     * @return array
     */
    private function checkOrderFlag($flag,$orderNo){
        $renovationModel=M('RenovationOrder');
        $repairModel=M('RepairOrder');
        $orders=array();
        if(empty($flag)){
            $repairOrder=$repairModel->where(array("repair_order_num_alias"=>$orderNo))->find();
            if(!empty($repairOrder)){
                $orders["order_id"]=$repairOrder["repair_order_id"];
                $orders["order_type"]=1;
                $orders["user_id"]=$repairOrder["user_id"];
                $orders['worker_user_id'] = $repairOrder["worker_user_id"];
            }else{
                $renovationOrder=$renovationModel->where(array("renovation_order_num_alias"=>$orderNo))->find();
                if(!empty($renovationOrder)){
                    $orders["order_id"]=$renovationOrder["renovation_order_id"];
                    $orders["order_type"]=2;
                    $orders["user_id"]=$renovationOrder["user_id"];
                }else{
                    $purifier = M('WaterPurifierOrder');
                    $map['order_num'] = $orderNo;
                    $purifierOrder = $purifier->where($map)->find();
                    if(!empty($purifierOrder)){
                        $orders["order_id"] = $purifierOrder["order_id"];
                        $orders["order_type"] = 4;
                        $orders["user_id"] = $purifierOrder["user_id"];
                    }
                }
            }
        }else{
            if($flag==1){
                $repairOrder=$repairModel->where(array("repair_order_num_alias"=>$orderNo))->find();
                if(!empty($repairOrder)){
                    $orders["order_id"]=$repairOrder["repair_order_id"];
                    $orders["order_type"]=1;
                    $orders["user_id"]=$repairOrder["user_id"];
                    $orders['worker_user_id'] = $repairOrder["worker_user_id"];
                }
            }else if($flag==2){
                $renovationOrder=$renovationModel->where(array("renovation_order_num_alias"=>$orderNo))->find();
                if(!empty($renovationOrder)){
                    $orders["order_id"]=$renovationOrder["renovation_order_id"];
                    $orders["order_type"]=2;
                    $orders["user_id"]=$renovationOrder["user_id"];
                }
            }else if ($flag == 4){ //净水器订单
                $purifier = M('WaterPurifierOrder');
                $map['order_num'] = $orderNo;
                $purifierOrder = $purifier->where($map)->find();
                if(!empty($purifierOrder)){
                    $orders["order_id"] = $purifierOrder["order_id"];
                    $orders["order_type"] = 4;
                    $orders["user_id"] = $purifierOrder["user_id"];
                }
            }
        }
        return $orders;
    }

    /**
     * 更新用户支付记录
     * @param $orderNo
     * @param $order_flag
     * @param $event
     * @param int $event_type 订单事件类型 1普通订单 2退款
     * @param int $user_id
     * @return bool|mixed
     */
    private function updateUserPayRecord($orderNo,$order_flag,$event,$event_type=1,$user_id=0){
        $result=false;
        if(!empty($event)){
            $charge = $event['data']['object'];
            $payData=array();
            $payData["user_id"]= $user_id;
            $payData["event"]= $event_type;
            $payData["ping_id"]=$charge["id"];
            $payData["created"]=$event["created"];
            $payData["status"]=1;
            $isExists=M("UserPayRecord")->where(array("order_id"=>$orderNo,"event"=>$event_type))->find();
            if(empty($isExists)){
                $payData["amount"]=$charge["amount"];
                $payData["subject"]=$charge["subject"];
                $payData["body"]=$charge["body"];
                $payData["order_type"]=$order_flag;
                //订单总计
                $payData["total"] =$charge["amount"];
                $payData["order_no"]=$orderNo;
                $payData["client_ip"]=$charge["client_ip"];
                $extra=$charge["extra"];
                $pay_extra=serialize($extra);
                $payData["extra"]=$pay_extra;
                $payData["addtime"]=time();
                $result=M("UserPayRecord")->add($payData);

                \Think\Log::record("pay-result-updateUserPayRecord-add:".$result." UserPayRecord===".var_export($payData,true));
            }else{
                $result=M("UserPayRecord")->where(array("order_id"=>$orderNo,"event"=>$event_type))->save($payData);
                \Think\Log::record("pay-result-updateUserPayRecord-edit:".$result." UserPayRecord===".var_export($isExists,true));
            }
        }
        return $result;
    }

    /**
     * 推送消息
     * @param $money
     * @param $user_id
     */
    private function pushPayInfo($money,$user_id){
        $userData=$this->checkUserIsExist($user_id);
        if(!isset($userData["code"])){
            $users=$userData["users"];
            //$jpushObj = new \Org\Util\JPush_test();
            $receive = $users["push_name"];//别名
            if(!empty($receive)&&!empty($money)){
                $content = '您已经成功向师傅付款￥'.$money."元";
                $m_type = 'tb';
                $m_txt = "";
                $m_time = '600';        //离线保留时间
                jpushStr($receive,$content);
                //$res = $jpushObj->jpush($receive, $content, $m_type, $m_txt, $m_time);
            }
        }
    }

    /**
     * 支付成功后取消订单
     * @param order_id 对外订单号
     */
    private function cancel($event){
        $charge = $event['data']['object']['metadata'];
        $order_id = $charge['order_id'];
        $amount = $event['data']['object']['amount']/100;
        file_put_contents("/tmp/test.txt",'RepairCancelPayMoney=========='.var_export($event,true)."\r\n",FILE_APPEND);
        $RepairOrder = M('repair_order')->field('repair_order_id,status,user_id,worker_user_id,protocol_id,repair_order_num_alias')->where("repair_order_num_alias = $order_id")->find();
        $repair_order_id = $RepairOrder['repair_order_id']; //对内订单号
        $user_id = $RepairOrder['user_id'];
        $worker_user_id = $RepairOrder['worker_user_id'];
        file_put_contents("/tmp/test.txt",'RepairCancelPayMoneyWorkerUser=========='.var_export($worker_user_id,true)."\r\n",FILE_APPEND);
        if($RepairOrder['status']=='-1'){
            $data['code'] = 404;
            $data['msg'] = '订单已取消';
            return $data;
        }
        $model = M();
        $model ->startTrans();

        if(!empty($charge['order_cancel_reason'])){
            $info['reason'] = $charge['order_cancel_reason'];  //取消原因
        }
        if(!empty($charge['order_cancel_content'])){
            $info['content'] = $charge['order_cancel_content']; //取消内容
        }

        $repair['repair_order_id'] = $repair_order_id;
        $repair['status'] = '-1';
        $order_Save = M('repair_order')->save($repair);

        $info['order_id'] =$repair_order_id;
        $info['user_id'] = $user_id;
        $info['add_time'] = time();
        $order_Cancel = M('repair_order_cancel')->add($info);

        $status['order_type'] = 1;
        $status['order_id'] = $repair_order_id;
        $status['add_time'] = time();
        $status['status'] = '-1';
        $order_status = M('order_status_history')->add($status);

        //诊断费添加到用户钱包
        $UserMoney = M('user_money')->where("user_id = $worker_user_id")->setInc('balance',$amount);
        //添加流水
        $this->addToMoneyHistory($worker_user_id,4,$RepairOrder['repair_order_id'],$RepairOrder['protocol_id'],$amount,1,NULL,5,"订单".$RepairOrder['repair_order_num_alias']."取消成功，诊断费已到余额");


        if($order_Cancel && $order_Save && $order_status && $UserMoney){
            $model->commit();
            S(C('REPAIR_ORDER') . '_key_' . $order_id,2,60);
            $push['user_id'] = $user_id;
            $push['order_id'] = $repair_order_id;
            $push['status'] = '2';
            M('pushorder')->save($push);

            $data['code'] = 200;
            $data['msg'] = '修改成功';
        }else{
            $model->rollback();
            $data['code'] = 403;
            $data['msg'] = '修改失败';
        }

        return $data;
    }

    /**
     * 支付成功后更改记录表状态
     */
    private function UpdateCancelRecord($event,$status){
        $result = false;
        if(!empty($event)){
            $order_id = $event['data']['object']['order_no'];
            $cancelRecord = M('user_pay_cancel_record')->where("order_no = $order_id")->find();
            if(!empty($cancelRecord)){
                $charge = $event['data']['object'];
                $where['order_no'] = $order_id;
                $maps['ping_id'] = $charge['id'];
                $maps['created'] = $charge['created'];
                $maps['status'] = 1;
                $maps['cancel_status'] = $status;
                $maps['is_fund'] = $status;
                $result = M('user_pay_cancel_record')->where($where)->save($maps);
            }
        }
        return $result;
    }

    /**
     * 发票支付成功更改状态
     */
    private function invoiceSuccess($event){
        $result = false;
        $data=$metadata=array();
        if(empty($event)){
            $data["code"]=403;
            $data["msg"]="非法操作";
            return $data;
        }

        $invoice=M('invoice');
        $id = $event['id'];
        $where['id']=$id;
        $is_exist=$invoice->where($where)->find();
        if($is_exist){
            $save['is_pay']=1;
            $result =  M('invoice')->where($where)->save($save);
        }
        return $result;
    }

    /**
     * 客服同意退款
     * @order_id 对外订单id
     * @amount  总金额
     * @description 理由
     */

    public function AgreeRefund(){
        $order_id = I('post.order_id');
        $description = I('post.description');
        $OrderExist = M('repair_order')->field('repair_order_num_alias')->where("repair_order_id = $order_id")->find();
        if(!$OrderExist){
            echo 3; //该订单不存在
            exit;
        }
        $UserPay = M('user_pay_record')->field('ping_id,channel')->where("order_no = $OrderExist[repair_order_num_alias] and status = 1")->find();
        if(!$UserPay){
            echo 2; //该订单未支付
            exit;
        }
        $UserRefund = M('repair_order_refund')->field('money')->where("order_id = $order_id")->find();
        $amount = $UserRefund['money'];
        $charge_id = $UserPay['ping_id'];
        if($UserPay['channel']=='wx'){
             $this->refund($charge_id,$amount,$description);
             $refundSucc =  M('repair_order_refund')->where("order_id = $order_id and status = 1")->find();
             if($refundSucc){
                 echo 1;
                 exit;
             }
        }elseif($UserPay['channel']=='alipay'){
            $result = $this->refund($charge_id,$amount,$description);
            echo $result;
            exit;
        }

    }

    /**
     * 创建唯一guid码
     */

    private function getGuid(){
        $charid = strtoupper(md5(uniqid(mt_rand(), true)));
        return $charid;
    }

    /**
     * 资金流水
     * @remark 维修金、维保金、小费
     */

    private function addToMoneyHistory($user_id,$type,$order_id,$protocol_id,$total,$is_plus,$balance,$flag,$remark){
        $UserMoneyHistory = M('MoneyHistory');
        $addMaps['user_id'] = $user_id;
        $addMaps['type'] = $type;
        $addMaps['order_id'] = $order_id;
        $addMaps['protocol_id'] = $protocol_id;
        $addMaps['total'] = $total;
        $addMaps['is_plus'] = $is_plus;
        $addMaps['flag'] = $flag;
        $addMaps['balance'] = $balance;
        $addMaps['remark'] = $remark;
        $addMaps['add_time'] = time();
        $UserMoneyHistory->add($addMaps);
    }


    private function genWaterPurifierOrder($data)
    {
        $result = array('msg'=>'', 'result'=>false);

        $addrId = intval($data['wdAddressId']);
        $paymentCode = $data['channel'] == 'alipay' ? 1 : 2;
        $orderType = intval($data['wdType']);
        $userId = intval($data['user_id']);
        $user = M('user')->where(array('user_id'=>$userId))->find();
        if (!$user) {
            $result['result'] = false;
            $result['msg'] = '用户信息错误';
            return $result;
        }

        $addr = M('address');
        $map['id'] = $addrId;
        $map['user_id'] = $userId;
        $address = $addr->where($map)->find();
        if (!$address) {
            $result['result'] = false;
            $result['msg'] = '用户地址错误';
            return $result;
        }
        
        if (!in_array($orderType, array(1,2,3))) {
            $result['result'] = false;
            $result['msg'] = '订单类型错误';
            return $result;
        }

        
        //组装订单数据
        $order = array();
        $order['user_id'] = $userId;
        $order['shipping_tel'] = $address['phone'];
        $order['shipping_name'] = $address['contacts'];
        $order['shipping_addr'] = $address['address'];
        $order['doorplate'] = $address['doorplate'];
        $order['city'] = $address['city'];
        $order['province'] = $address['province'];
        $order['lng'] = $address['lng'];
        $order['lat'] = $address['lat'];
        $order['order_type'] = $orderType;
        $order['payment_code'] = $paymentCode;
        $order['add_time'] = time();
        $order['total'] = 0;
        $order['reduce'] = 0;
        $order['address_id'] = $addrId;
        $order['order_num'] = build_order_no();
        $order['ip'] = $_SERVER['REMOTE_ADDR'];
        $order['brand'] = $data['brand'];


        if ($orderType == 1) { //领取订单
            $res = $this->receiveOrder($order, $user['add_time'], $data['amount']);
        }else{ //维修更换订单
            $res = $this->replaceOrRepairOrder($order, $data['wdItem'], $data['amount']);
        }
        return $res;
    }

    /**
     * 领取净水器下单操作
     * @param  array $orrder      订单信息
     * @param  int $registerTime 用户注册时间
     * @return mixed               
     */
    private function receiveOrder($order, $registerTime = 0, $amount = 0)
    {
        //to do 限制下单数量
        $orderModel = M('WaterPurifierOrder');
        $detailModel = M('WaterPurifierOrderDetail');

        $result = array('msg'=>'', 'result'=>false);
        if (intval($registerTime) <= 0) {
            $result['result'] = false;
            $result['msg'] = '用户注册时间获取失败';
            return $result;
        }

        $map['order_type'] = 1;
        $map['user_id'] = $order['user_id'];
        $map['order_status'] = 1;
        $map['pay_time'] = array('gt', 0);
        $map['is_deleted'] = 0;
        $count = $orderModel->where($map)->count();
        if ($count) {
            $result['result'] = false;
            $result['msg'] = '每个用户只能领取一个净水器';
            return $result;
        }
        unset($map);
        //领取配置数据
        $purifier = M('WaterPurifier');
        $map['config_key'] = 'receive_activity_day';
        $map['brand'] = $order['brand'];
        $activityDay = $purifier->where($map)->getField('day');
        unset($map);
        $map['config_key'][] = array('LIKE', 'receive%');
        $map['config_key'][] = array('LIKE', '%price');
        $map['brand'] = $order['brand'];
        $price = $purifier->where($map)->select();
        $orderDetail = array();
        $detail = array();
        $second = $activityDay * 86400 - (time() - $registerTime);
       
         //组装订单详情数组
        foreach ($price as $v) {
            $detail['item_key'] = $v['config_key'];
            $detail['item_name'] = $v['config_value'];
            $detail['user_id'] = $order['user_id'];
            $detail['order_type'] = $order['order_type'];
            $detail['price'] = $v['price'];
            $detail['add_time'] = time();
            $detail['reduce'] = 0;
            $orderDetail[] = $detail;
        }
        //净水器实际价格
        $realMap['config_key'] = 'receive_actually_price';
        $realMap['brand'] = $order['brand'];
        $realPrice = $purifier->where($realMap)->getField('price');
        //计算订单支付金额和减免金额
        foreach ($orderDetail as $k => $v) {
            if($second > 0 and $v['item_key'] == 'receive_activity_price'){
                $orderDetail[$k]['reduce'] = bcsub($realPrice,$v['price'], 2);
                $order['reduce'] = bcsub($realPrice, $v['price'], 2);
            }
            if ($second <= 0 and $v['item_key'] == 'receive_activity_price') {
                unset($orderDetail[$k]);
            }
            if($v['item_key'] != 'receive_activity_price'){
                $order['total'] = bcadd($order['total'], $v['price'], 2);
                //$order['total'] += $v['price'];
            }
        }
        $orderDetail = array_merge($orderDetail);
        $order['actually_total'] = bcsub($order['total'], $order['reduce'], 2);
        //$order['actually_total'] = $order['total'] - $order['reduce'];
        $total = intval($order['actually_total'] * 100);
        if ($total != $amount) {
            Log::write(var_export($order['actually_total'],true),'total');
            Log::write(var_export($amount,true),'amount');
            $result['result'] = false;
            $result['msg'] = '订单金额错误';
            return $result;
        }
        //查找是否存在未支付的订单
        unset($map);
        $map['order_type'] = 1;
        $map['user_id'] = $order['user_id'];
        $map['order_status'] = 1;
        $map['pay_time'] = 0;
        $map['is_deleted'] = 0;
        $orderId = $orderModel->where($map)->order('add_time desc')->getField('order_id');

        //插入或更新订单数据
        $orderModel->startTrans();
        if ($orderId) {
            $updateMap['order_id'] = $orderId;
            unset($order['order_num']);
            $orderModel->where($updateMap)->save($order);
            $detailModel->where($updateMap)->save(array('is_deleted'=>1));
        }else{
            $orderId = $orderModel->add($order);
        }

        if ($orderId) {
            foreach ($orderDetail as $k => $v) {
                $orderDetail[$k]['order_id'] = $orderId;
            }
            $res = $detailModel->addAll($orderDetail, array(), true);
            if ($res) {
                $orderModel->commit();
                $result['result'] = true;
                $result['msg'] = $orderId;
                return $result;
                //return $orderId; 
            }else{
                $orderModel->rollback();
                $result['result'] = false;
                $result['msg'] = '下单失败';
                return $result;
            }
        }else{
            $orderModel->rollback();
            $result['result'] = false;
            $result['msg'] = '下单失败';
            return $result;
        }
    }

    private function replaceOrRepairOrder($order, $items = '', $amount = 0)
    {
        $orderModel = M('WaterPurifierOrder');
        $detailModel = M('WaterPurifierOrderDetail');

        $result = array('msg'=>'', 'result'=>false);

        //更换配置数据
        $purifier = M('WaterPurifier');
        $items = explode(',', $items);
        if (empty($items)) {
            $result['result'] = false;
            $result['msg'] = '更换或维修项目不能为空';
            return $result;
        }

        $orderDetail = array();
        $detail = array();
        foreach ($items as $k => $v) {
            unset($map);
            $map['config_key'][] = array('eq', $v);
            $map['brand'] = $order['brand'];
            $map['status'] = 1;
            $map['is_deleted'] = 0;
            if($order['order_type'] == 2){
                $map['config_key'][] = array('LIKE', 'replace%');
            }else{
                $map['config_key'][] = array('LIKE', 'repair%');
            }
            $config = $purifier->where($map)->find();

            if (!$config) {
                $result['result'] = false;
                $result['msg'] = '更换或维修项目错误';
                return $result;
            }
            $detail['item_key'] = $config['config_key'];
            $detail['item_name'] = $config['config_value'];
            $detail['user_id'] = $order['user_id'];
            $detail['order_type'] = $order['order_type'];
            $detail['price'] = $config['price'];
            $detail['add_time'] = time();
            $detail['reduce'] = 0;
            $orderDetail[] = $detail;
            $order['total'] = bcadd($order['total'], $config['price'], 2);
            //$order['total'] += $config['price'];
        }
        $order['actually_total'] = $order['total'];
        $total = $order['actually_total'] * 100;
        $total = intval($total);
        if ($total != $amount) {
            $result['result'] = false;
            $result['msg'] = '订单金额错误';
            return $result;
        }
        //查找是否存在未支付的订单
        unset($map);
        $map['order_type'] = $order['order_type'];
        $map['user_id'] = $order['user_id'];
        $map['order_status'] = 1;
        $map['pay_time'] = 0;
        $map['is_deleted'] = 0;
        $orderId = $orderModel->where($map)->order('add_time desc')->getField('order_id');
        
        if ($orderId) {
            $updateMap['order_id'] = $orderId;
            unset($order['order_num']);
            $orderModel->where($updateMap)->save($order);
            $detailModel->where($updateMap)->save(array('is_deleted'=>1));
        }else{
            $orderId = $orderModel->add($order);
        }
        //插入或更新订单数据
        $orderModel->startTrans();
        if ($orderId) {
            foreach ($orderDetail as $k => $v) {
                $orderDetail[$k]['order_id'] = $orderId;
            }
            $res = $detailModel->addAll($orderDetail, array(), true);
            if ($res) {
                $orderModel->commit();
                $result['result'] = true;
                $result['msg'] = $orderId;
                return $result;
            }else{
                $orderModel->rollback();
                $result['result'] = false;
                $result['msg'] = '下单失败';
                return $result;
            }
        }else{
            $orderModel->rollback();
            $result['result'] = false;
            $result['msg'] = '下单失败';
            return $result;
        }
    }
}